package com.infore.qualityControl.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.infore.qualityControl.bo.QualityParamAnalysisBo;
import com.infore.qualityControl.bo.QualityParamOutSelectBo;
import com.infore.qualityControl.constant.Constants;
import com.infore.qualityControl.enums.QualityAnalysisEnum;
import com.infore.qualityControl.enums.ResultStatus;
import com.infore.qualityControl.po.FiveParameter;
import com.infore.qualityControl.po.IntegratedIntervention;
import com.infore.qualityControl.po.MultipointLinearity;
import com.infore.qualityControl.po.RealWaterSampleComparison;
import com.infore.qualityControl.po.Recovery;
import com.infore.qualityControl.po.SpanDrift;
import com.infore.qualityControl.po.ZeroDrift;
import com.infore.qualityControl.remoteService.IDataAuditService;
import com.infore.qualityControl.remoteService.ISiteManageService;
import com.infore.qualityControl.repository.IFiveParameterRepository;
import com.infore.qualityControl.repository.IIntegratedInterventionRepository;
import com.infore.qualityControl.repository.IMultipointLinearityRepository;
import com.infore.qualityControl.repository.IRealWaterSampleComparisonRepository;
import com.infore.qualityControl.repository.IRecoveryRepository;
import com.infore.qualityControl.repository.ISpanDriftRepository;
import com.infore.qualityControl.repository.IZeroDriftRepository;
import com.infore.qualityControl.select.util.PageObject;
import com.infore.qualityControl.service.IQualityAnalysisService;
import com.infore.qualityControl.service.IVerificationService;
import com.infore.qualityControl.util.ArrayUtils;
import com.infore.qualityControl.util.DateUtil;
import com.infore.qualityControl.util.ObjectMapperUtil;
import com.infore.qualityControl.util.Page;
import com.infore.qualityControl.util.PageUtil;
import com.infore.qualityControl.util.ResultEntity;
import com.infore.qualityControl.util.ScaleUtil;

@Service
public class QualityAnalysisServiceImpl implements IQualityAnalysisService {

    @Autowired
    IVerificationService IVerificationService;

    @Autowired
    IZeroDriftRepository IZeroDriftRepository;

    @Autowired
    ISpanDriftRepository ISpanDriftRepository;

    @Autowired
    IFiveParameterRepository IFiveParameterRepository;

    @Autowired
    IMultipointLinearityRepository IMultipointLinearityRepository;

    @Autowired
    IIntegratedInterventionRepository IIntegratedInterventionRepository;

    @Autowired
    IRealWaterSampleComparisonRepository IRealWaterSampleComparisonRepository;

    @Autowired
    IRecoveryRepository IRecoveryRepository;

    @Autowired
    IDataAuditService IDataAuditService;

    @Autowired
    ISiteManageService ISiteManageService;

    @Autowired
    ObjectMapperUtil ObjectMapperUtil;

    // 月度报表台账周质控查询监测项目参数
    public static final List<String> WEEK_QUALITY_INDEX = new ArrayList<>(Arrays.asList("w01001", "w01010", "w01009", "w01014"));

    @Override
    public ResultEntity dayQualityControllerData(QualityParamAnalysisBo qualityParamAnalysisBo, PageObject pageObject) {
        ResultEntity resultEntity = IVerificationService.verificationQualityAnalysis(qualityParamAnalysisBo);
        if (resultEntity.getCode() == 1) {
            return resultEntity;
        }
        boolean pageFlag = pageObject.getPageNumber() != null && pageObject.getPageSize() != null;
        if (pageFlag) {

        }
        return null;
    }

    @SuppressWarnings("unchecked")
    @Override
    public ResultEntity qualityControllerExamineData(QualityParamAnalysisBo qualityParamAnalysisBo, PageObject pageObject) {
        ResultEntity resultEntity = IVerificationService.verificationQualityAnalysis(qualityParamAnalysisBo);
        if (resultEntity.getCode() == 1) {
            return resultEntity;
        }
        Date startDate = DateUtil.dangyueDiyitianDay(DateUtil.stringToDate(qualityParamAnalysisBo.getStartTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        Date endDate = DateUtil.getLastDayDayM(DateUtil.stringToDate(qualityParamAnalysisBo.getEndTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        // 字符串转集合
        List<String> stationCodeList = ArrayUtils.stringToList(qualityParamAnalysisBo.getStationCodes());
        // 获取质控类型
        String qualityAnalysisType = qualityParamAnalysisBo.getQualityAnalysisType();
        List<Map<String, Object>> list = null;
        // 返回的结果集
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        Map<String, Object> valueMap = new HashMap<String, Object>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        // 日质控封装
        if (QualityAnalysisEnum.DAY_QUALITY.getCode().equals(qualityAnalysisType)) {
            List<Map<String, Object>> zeroList = IZeroDriftRepository.getZeroDriftExamineData(startDate, endDate, stationCodeList);
            List<Map<String, Object>> spanList = ISpanDriftRepository.getSpanDriftExamineData(startDate, endDate, stationCodeList);
            for (Map<String, Object> zeroMap : zeroList) {
                String areaName = zeroMap.get("AREA_NAME").toString();
                String basinName = zeroMap.get("BASIN_NAME").toString();
                String zeroStationCode = zeroMap.get("STATION_CODE").toString();
                String zeroStationName = zeroMap.get("STATION_NAME").toString();
                String zeroIndexCode = zeroMap.get("INDEX_CODE").toString();
                Double zeroCount = Double.valueOf(zeroMap.get("COUNT").toString()); // 总数量
                Double zeroQualified = Double.valueOf(zeroMap.get("LAST_QUALIFICATION").toString()); // 合格数量
                String zeroQualifiedRate = ScaleUtil.sciCalSix(zeroQualified * 100 / zeroCount, 1) + "%"; // 计算合格率
                if (!valueMap.containsKey(zeroStationCode)) {
                    resultMap = new HashMap<String, Object>();
                    result.add(resultMap);
                    valueMap.put(zeroStationCode, resultMap);
                    resultMap.put("areaName", areaName);
                    resultMap.put("basinName", basinName);
                    resultMap.put("stationName", zeroStationName);
                    // 遍历跨度漂移数据
                    for (Map<String, Object> map : spanList) {
                        String spanStationCode = map.get("STATION_CODE").toString();
                        String spanIndexCode = map.get("INDEX_CODE").toString();
                        Double spanCount = Double.valueOf(map.get("COUNT").toString()); // 总数量
                        Double spanQualified = Double.valueOf(map.get("LAST_QUALIFICATION").toString()); // 合格数量
                        String spanQualifiedRate = ScaleUtil.sciCalSix(spanQualified * 100 / spanCount, 1) + "%"; // 计算合格率
                        if (zeroStationCode.equals(spanStationCode)) { // 根据站点ID匹配,将跨度漂移数据放入同一个map里
                            resultMap.put("span_" + spanIndexCode + "_count", spanCount);
                            resultMap.put("span_" + spanIndexCode + "_qualified", spanQualified);
                            resultMap.put("span_" + spanIndexCode + "_qualifiedRate", spanQualifiedRate);
                        }
                    }
                } else {
                    resultMap = (Map<String, Object>) valueMap.get(zeroStationCode);
                }
                resultMap.put("zero_" + zeroIndexCode + "_count", zeroCount);
                resultMap.put("zero_" + zeroIndexCode + "_qualified", zeroQualified);
                resultMap.put("zero_" + zeroIndexCode + "_qualifiedRate", zeroQualifiedRate);
            }
        } else if (QualityAnalysisEnum.FIVE_PARAM.getCode().equals(qualityAnalysisType)) {
            list = IFiveParameterRepository.getFiveParameterExamineData(startDate, endDate, stationCodeList);
        } else if (QualityAnalysisEnum.MULTIPOINT_LINEARITY.getCode().equals(qualityAnalysisType)) {
            list = IMultipointLinearityRepository.getMultipointLinearityExamineData(startDate, endDate, stationCodeList);
        } else if (QualityAnalysisEnum.INTEGRATED_INTERVENTION.getCode().equals(qualityAnalysisType)) {
            list = IIntegratedInterventionRepository.getIntegratedInterventionExamineData(startDate, endDate, stationCodeList);
        } else if (QualityAnalysisEnum.REAL_WATER_SAMPLE_COMPARISON.getCode().equals(qualityAnalysisType)) {
            list = IRealWaterSampleComparisonRepository.getRealWaterSampleComparisonExamineData(startDate, endDate, stationCodeList);
        } else if (QualityAnalysisEnum.RECOVERY.getCode().equals(qualityAnalysisType)) {
            list = IRecoveryRepository.getRecoveryExamineData(startDate, endDate, stationCodeList);
        }
        // 常规五参数、多点线性、集成干预、实际水样、加标回收率数据封装
        if (!QualityAnalysisEnum.DAY_QUALITY.getCode().equals(qualityAnalysisType)) {
            for (Map<String, Object> map : list) {
                String areaName = map.get("AREA_NAME").toString();
                String basinName = map.get("BASIN_NAME").toString();
                String stationCode = map.get("STATION_CODE").toString();
                String stationName = map.get("STATION_NAME").toString();
                String indexCode = map.get("INDEX_CODE").toString();
                Double count = Double.valueOf(map.get("COUNT").toString()); // 总数量
                Double qualified = Double.valueOf(map.get("QUALIFIED").toString()); // 合格数量
                String qualifiedRate = ScaleUtil.sciCalSix(qualified * 100 / count, 1) + "%"; // 计算合格率
                if (!valueMap.containsKey(stationCode)) {
                    resultMap = new HashMap<String, Object>();
                    result.add(resultMap);
                    valueMap.put(stationCode, resultMap);
                } else {
                    resultMap = (Map<String, Object>) valueMap.get(stationCode);
                }
                resultMap.put("areaName", areaName);
                resultMap.put("basinName", basinName);
                resultMap.put("stationName", stationName);
                resultMap.put(indexCode + "_count", count);
                resultMap.put(indexCode + "_qualified", qualified);
                resultMap.put(indexCode + "_qualifiedRate", qualifiedRate);
            }
        }
        boolean pageFlag = pageObject != null && pageObject.getPageNumber() != null && pageObject.getPageSize() != null;
        if (pageFlag) {
            Page<Map<String, Object>> page = PageUtil.inventedPage(result, pageObject);
            return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(result);
    }

    @Override
    public ResultEntity effectivenessData(QualityParamAnalysisBo qualityParamAnalysisBo, PageObject pageObject) {
        ResultEntity resultEntity = IVerificationService.verificationQualityAnalysis(qualityParamAnalysisBo);
        if (resultEntity.getCode() == 1) {
            return resultEntity;
        }
        // 字符串转集合
        List<String> stationCodeList = ArrayUtils.stringToList(qualityParamAnalysisBo.getStationCodes());
        // 封装远程调用的请求参数
        QualityParamOutSelectBo qualityParamOutSelectBo = new QualityParamOutSelectBo();
        qualityParamOutSelectBo.setStartTime(qualityParamAnalysisBo.getStartTime());
        qualityParamOutSelectBo.setEndTime(qualityParamAnalysisBo.getEndTime());
        qualityParamOutSelectBo.setStationCodes(stationCodeList);
        qualityParamOutSelectBo.setPageNumber(pageObject.getPageNumber());
        qualityParamOutSelectBo.setPageSize(pageObject.getPageSize());
        return IDataAuditService.queryAuditDataByTimeAndMns(qualityParamOutSelectBo);
    }

    @Override
    public ResultEntity singleMonthExamineInstrumentData(QualityParamAnalysisBo qualityParamAnalysisBo, PageObject pageObject) {
        return ISiteManageService.queryEquipments(qualityParamAnalysisBo.getStationCodes());
    }

    @SuppressWarnings("unchecked")
    @Override
    public ResultEntity singleMonthExamineQualityData(QualityParamAnalysisBo qualityParamAnalysisBo, PageObject pageObject) {
        ResultEntity resultEntity = IVerificationService.verificationQualityAnalysis(qualityParamAnalysisBo);
        if (resultEntity.getCode() == 1) {
            return resultEntity;
        }
        Date startDate = DateUtil.dangyueDiyitianDay(DateUtil.stringToDate(qualityParamAnalysisBo.getStartTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        Date endDate = DateUtil.getLastDayDayM(DateUtil.stringToDate(qualityParamAnalysisBo.getEndTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        // 字符串转集合
        List<String> stationCodeList = ArrayUtils.stringToList(qualityParamAnalysisBo.getStationCodes());
        // 获取数据集
        List<ZeroDrift> zeroList = IZeroDriftRepository.findByTimeBetweenAndStationCodeInOrderByTimeDesc(startDate, endDate,
                stationCodeList);
        List<SpanDrift> spanList = ISpanDriftRepository.findByTimeBetweenAndStationCodeInOrderByTimeDesc(startDate, endDate,
                stationCodeList);
        // 返回的结果集
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        Map<String, Object> valueMap = new HashMap<String, Object>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        // 数据封装(因为零点漂移与跨度漂移的时间点不一样,故分两次循环)
        for (ZeroDrift zeroDrift : zeroList) {
            String zeroIndexCode = zeroDrift.getIndexCode();
            String zeroValue = zeroDrift.getValue(); // 零点核查系统值
            String zeroLastValue = zeroDrift.getLastValue(); // 零点漂移
            String zeroTime = DateUtil.dateToString(zeroDrift.getTime(), DateUtil.DATE_SMALL_YMDHMS);
            if (!valueMap.containsKey(zeroTime)) {
                resultMap = new HashMap<String, Object>();
                resultMap.put("time", zeroTime);
                result.add(resultMap);
                valueMap.put(zeroTime, resultMap);
            } else {
                resultMap = (Map<String, Object>) valueMap.get(zeroTime);
            }
            resultMap.put(zeroIndexCode + "_zeroValue", zeroValue);
            resultMap.put(zeroIndexCode + "_zeroLastValue", zeroLastValue);
            resultMap.put(zeroIndexCode + "_spanValue", "");
            resultMap.put(zeroIndexCode + "_spanLastValue", "");
        }
        for (SpanDrift spanDrift : spanList) {
            String spanIndexCode = spanDrift.getIndexCode();
            String spanValue = spanDrift.getValue(); // 跨度核查系统值
            String spanLastValue = spanDrift.getLastValue(); // 跨度漂移
            String spanTime = DateUtil.dateToString(spanDrift.getTime(), DateUtil.DATE_SMALL_YMDHMS);
            if (!valueMap.containsKey(spanTime)) {
                resultMap = new HashMap<String, Object>();
                resultMap.put("time", spanTime);
                result.add(resultMap);
                valueMap.put(spanTime, resultMap);
            } else {
                resultMap = (Map<String, Object>) valueMap.get(spanTime);
            }
            resultMap.put(spanIndexCode + "_spanValue", spanValue);
            resultMap.put(spanIndexCode + "_spanLastValue", spanLastValue);
            resultMap.put(spanIndexCode + "_zeroValue", "");
            resultMap.put(spanIndexCode + "_zeroLastValue", "");
        }
        // 排序 默认按照时间降序排序
        Collections.sort(result, new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> map1, Map<String, Object> map2) {
                Long l1 = 0L;
                Long l2 = 0L;
                try {
                    if (map1.get("time") != null) {
                        l1 = DateUtil.stringToDate(map1.get("time").toString(), DateUtil.DATE_SMALL_YMDHMS).getTime();
                    }
                    if (map2.get("time") != null) {
                        l2 = DateUtil.stringToDate(map2.get("time").toString(), DateUtil.DATE_SMALL_YMDHMS).getTime();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return l2 > l1 ? 1 : -1;
            }
        });
        boolean pageFlag = pageObject != null && pageObject.getPageNumber() != null && pageObject.getPageSize() != null;
        if (pageFlag) {
            Page<Map<String, Object>> page = PageUtil.inventedPage(result, pageObject);
            return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(result);
    }

    @SuppressWarnings("unchecked")
    @Override
    public ResultEntity singleMonthExamineFiveParameterData(QualityParamAnalysisBo qualityParamAnalysisBo, PageObject pageObject) {
        ResultEntity resultEntity = IVerificationService.verificationQualityAnalysis(qualityParamAnalysisBo);
        if (resultEntity.getCode() == 1) {
            return resultEntity;
        }
        Date startDate = DateUtil.dangyueDiyitianDay(DateUtil.stringToDate(qualityParamAnalysisBo.getStartTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        Date endDate = DateUtil.getLastDayDayM(DateUtil.stringToDate(qualityParamAnalysisBo.getEndTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        // 字符串转集合
        List<String> stationCodeList = ArrayUtils.stringToList(qualityParamAnalysisBo.getStationCodes());
        // 获取数据集
        List<FiveParameter> list = IFiveParameterRepository.findByTimeBetweenAndStationCodeInOrderByTimeDesc(startDate, endDate,
                stationCodeList);
        // 返回的结果集
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        Map<String, Object> valueMap = new HashMap<String, Object>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        // 数据封装
        for (FiveParameter fiveParameter : list) {
            String indexCode = fiveParameter.getIndexCode();
            String value = fiveParameter.getValue(); // 测定值
            String standardSamplesValue = fiveParameter.getStandardSamplesValue(); // 标样值
            String qualification = fiveParameter.getQualification(); // 合格情况
            String time = DateUtil.dateToString(fiveParameter.getTime(), DateUtil.DATE_FULL_STR);
            if (!valueMap.containsKey(time)) {
                resultMap = new HashMap<String, Object>();
                resultMap.put("time", time);
                result.add(resultMap);
                valueMap.put(time, resultMap);
            } else {
                resultMap = (Map<String, Object>) valueMap.get(time);
            }
            resultMap.put(indexCode + "_value", value);
            resultMap.put(indexCode + "_standardSamplesValue", standardSamplesValue);
            resultMap.put(indexCode + "_qualification", qualification);
        }
        boolean pageFlag = pageObject != null && pageObject.getPageNumber() != null && pageObject.getPageSize() != null;
        if (pageFlag) {
            Page<Map<String, Object>> page = PageUtil.inventedPage(result, pageObject);
            return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(result);
    }

    @Override
    public ResultEntity singleMonthExamineMultipointlinearityData(QualityParamAnalysisBo qualityParamAnalysisBo, PageObject pageObject) {
        ResultEntity resultEntity = IVerificationService.verificationQualityAnalysis(qualityParamAnalysisBo);
        if (resultEntity.getCode() == 1) {
            return resultEntity;
        }
        Date startDate = DateUtil.dangyueDiyitianDay(DateUtil.stringToDate(qualityParamAnalysisBo.getStartTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        Date endDate = DateUtil.getLastDayDayM(DateUtil.stringToDate(qualityParamAnalysisBo.getEndTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        // 字符串转集合
        List<String> stationCodeList = ArrayUtils.stringToList(qualityParamAnalysisBo.getStationCodes());
        // 获取数据集
        List<MultipointLinearity> list = IMultipointLinearityRepository.findByTimeBetweenAndStationCodeInOrderByIndexCodeDesc(startDate,
                endDate, stationCodeList);
        // 返回的结果集
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        Map<String, Object> valueMap = new HashMap<String, Object>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        // 数据封装
        boolean pageFlag = pageObject != null && pageObject.getPageNumber() != null && pageObject.getPageSize() != null;
        if (pageFlag) {
            Page<Map<String, Object>> page = PageUtil.inventedPage(result, pageObject);
            return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(result);
    }

    @Override
    public ResultEntity singleMonthExamineIntegratedInterventionData(QualityParamAnalysisBo qualityParamAnalysisBo, PageObject pageObject) {
        ResultEntity resultEntity = IVerificationService.verificationQualityAnalysis(qualityParamAnalysisBo);
        if (resultEntity.getCode() == 1) {
            return resultEntity;
        }
        Date startDate = DateUtil.dangyueDiyitianDay(DateUtil.stringToDate(qualityParamAnalysisBo.getStartTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        Date endDate = DateUtil.getLastDayDayM(DateUtil.stringToDate(qualityParamAnalysisBo.getEndTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        // 字符串转集合
        List<String> stationCodeList = ArrayUtils.stringToList(qualityParamAnalysisBo.getStationCodes());
        // 获取数据集
        List<IntegratedIntervention> list = IIntegratedInterventionRepository.findByTimeBetweenAndStationCodeInOrderByTimeDesc(startDate,
                endDate, stationCodeList);
        boolean pageFlag = pageObject != null && pageObject.getPageNumber() != null && pageObject.getPageSize() != null;
        if (pageFlag) {
            Page<IntegratedIntervention> page = PageUtil.inventedObjectPage(list, pageObject);
            return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
    }

    @Override
    public ResultEntity singleMonthExamineRecoveryData(QualityParamAnalysisBo qualityParamAnalysisBo, PageObject pageObject) {
        ResultEntity resultEntity = IVerificationService.verificationQualityAnalysis(qualityParamAnalysisBo);
        if (resultEntity.getCode() == 1) {
            return resultEntity;
        }
        Date startDate = DateUtil.dangyueDiyitianDay(DateUtil.stringToDate(qualityParamAnalysisBo.getStartTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        Date endDate = DateUtil.getLastDayDayM(DateUtil.stringToDate(qualityParamAnalysisBo.getEndTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        // 字符串转集合
        List<String> stationCodeList = ArrayUtils.stringToList(qualityParamAnalysisBo.getStationCodes());
        // 获取数据集
        List<Recovery> list = IRecoveryRepository.findByTimeBetweenAndStationCodeInOrderByTimeDesc(startDate, endDate, stationCodeList);
        for (Recovery recovery : list) {
            // 计算样品体积
            recovery.setSampleVolume(
                    String.valueOf(Double.valueOf(recovery.getWaterSampleVolume()) - Double.valueOf(recovery.getAddVolume())));
        }
        boolean pageFlag = pageObject != null && pageObject.getPageNumber() != null && pageObject.getPageSize() != null;
        if (pageFlag) {
            Page<Recovery> page = PageUtil.inventedObjectPage(list, pageObject);
            return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
    }

    @Override
    public ResultEntity singleMonthExamineRealWaterSampleComparisonData(QualityParamAnalysisBo qualityParamAnalysisBo,
            PageObject pageObject) {
        ResultEntity resultEntity = IVerificationService.verificationQualityAnalysis(qualityParamAnalysisBo);
        if (resultEntity.getCode() == 1) {
            return resultEntity;
        }
        Date startDate = DateUtil.dangyueDiyitianDay(DateUtil.stringToDate(qualityParamAnalysisBo.getStartTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        Date endDate = DateUtil.getLastDayDayM(DateUtil.stringToDate(qualityParamAnalysisBo.getEndTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        // 字符串转集合
        List<String> stationCodeList = ArrayUtils.stringToList(qualityParamAnalysisBo.getStationCodes());
        // 获取数据集
        List<RealWaterSampleComparison> list = IRealWaterSampleComparisonRepository
                .findByTimeBetweenAndStationCodeInOrderByTimeDesc(startDate, endDate, stationCodeList);
        boolean pageFlag = pageObject != null && pageObject.getPageNumber() != null && pageObject.getPageSize() != null;
        if (pageFlag) {
            Page<RealWaterSampleComparison> page = PageUtil.inventedObjectPage(list, pageObject);
            return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
    }

    @SuppressWarnings("unchecked")
    @Override
    public ResultEntity monthReportStandingBook(QualityParamAnalysisBo qualityParamAnalysisBo, PageObject pageObject) {
        ResultEntity resultEntity = IVerificationService.verificationQualityAnalysis(qualityParamAnalysisBo);
        if (resultEntity.getCode() == 1) {
            return resultEntity;
        }
        Date startDate = DateUtil.dangyueDiyitianDay(DateUtil.stringToDate(qualityParamAnalysisBo.getStartTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        Date endDate = DateUtil.getLastDayDayM(DateUtil.stringToDate(qualityParamAnalysisBo.getEndTime(), DateUtil.DATE_SMALL_STR),
                DateUtil.DATE_FULL_STR);
        // 字符串转集合
        List<String> stationCodeList = ArrayUtils.stringToList(qualityParamAnalysisBo.getStationCodes());
        // 获取质控类型
        String qualityAnalysisType = qualityParamAnalysisBo.getQualityAnalysisType();
        List<Map<String, Object>> list = null;
        // 返回的结果集
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        Map<String, Object> valueMap = new HashMap<String, Object>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        List<Double> qualifiedRateList = new ArrayList<Double>(); // 收集各站点的因子合格率数据
        List<Double> completionRateList = new ArrayList<Double>(); // 收集各站点的因子完成率数据
        int shouldTransmitted = 0;
        // 日质控封装
        if (QualityAnalysisEnum.DAY_QUALITY.getCode().equals(qualityAnalysisType)) {
            List<Map<String, Object>> zeroList = IZeroDriftRepository.getExamineData(startDate, endDate, stationCodeList);
            List<Map<String, Object>> spanList = ISpanDriftRepository.getExamineData(startDate, endDate, stationCodeList);
            shouldTransmitted = DateUtil.differentDays(startDate, endDate) + 1;
            for (Map<String, Object> zeroMap : zeroList) {
                String areaName = zeroMap.get("AREA_NAME").toString();
                String basinName = zeroMap.get("BASIN_NAME").toString();
                String zeroOperationName = zeroMap.get("OPERATION_NAME") == null ? "" : zeroMap.get("OPERATION_NAME").toString();
                String zeroStationCode = zeroMap.get("STATION_CODE").toString();
                String zeroStationName = zeroMap.get("STATION_NAME").toString();
                String zeroIndexCode = zeroMap.get("INDEX_CODE").toString();
                Double zeroCount = Double.valueOf(zeroMap.get("COUNT").toString()); // 总数量
                Double zeroQualified = Double.valueOf(zeroMap.get("QUALIFICATION").toString()); // 合格数量
                if (!valueMap.containsKey(zeroStationCode)) {
                    resultMap = new HashMap<String, Object>();
                    qualifiedRateList = new ArrayList<Double>();
                    completionRateList = new ArrayList<Double>();
                    result.add(resultMap);
                    valueMap.put(zeroStationCode, resultMap);
                    valueMap.put(zeroStationCode + "qualified", qualifiedRateList);
                    valueMap.put(zeroStationCode + "completion", completionRateList);
                    resultMap.put("areaName", areaName);
                    resultMap.put("basinName", basinName);
                    resultMap.put("operationName", zeroOperationName);
                    resultMap.put("stationName", zeroStationName);
                } else {
                    resultMap = (Map<String, Object>) valueMap.get(zeroStationCode);
                    qualifiedRateList = (List<Double>) valueMap.get(zeroStationCode + "qualified");
                    completionRateList = (List<Double>) valueMap.get(zeroStationCode + "completion");
                }
                // 遍历跨度漂移数据
                for (Map<String, Object> spanMap : spanList) {
                    String spanStationCode = spanMap.get("STATION_CODE").toString();
                    String spanIndexCode = spanMap.get("INDEX_CODE").toString();
                    Double spanCount = Double.valueOf(spanMap.get("COUNT").toString()); // 总数量
                    Double spanQualified = Double.valueOf(spanMap.get("QUALIFICATION").toString()); // 合格数量
                    if ((zeroStationCode + zeroIndexCode).equals(spanStationCode + spanIndexCode)) { // 根据站点ID与因子编码匹配
                        Double count = zeroCount >= spanCount ? zeroCount : spanCount; // 总数量取最大值
                        Double qualified = zeroQualified <= spanQualified ? zeroQualified : spanQualified; // 合格数量取最小值
                        String qualifiedRate = qualified == 0.0 || count == 0.0 ? "0" : ScaleUtil.sciCalSix(qualified * 100 / count, 1); // 计算合格率
                        String completionRate = qualified == 0.0 || shouldTransmitted == 0.0 ? "0"
                                : ScaleUtil.sciCalSix(qualified * 100 / shouldTransmitted, 1); // 计算完成率
                        resultMap.put(spanIndexCode + "_qualifiedRate", qualifiedRate);
                        resultMap.put(spanIndexCode + "_completionRate", completionRate);
                        qualifiedRateList.add(Double.valueOf(qualifiedRate));
                        completionRateList.add(Double.valueOf(completionRate));
                        resultMap.put("appraiseQualifiedRate", ScaleUtil
                                .sciCalSix(qualifiedRateList.stream().collect(Collectors.averagingDouble(Double::doubleValue)), 1)); // 评价合格率
                        resultMap.put("appraiseCompletionRate", ScaleUtil
                                .sciCalSix(completionRateList.stream().collect(Collectors.averagingDouble(Double::doubleValue)), 1)); // 评价完成率
                        break;
                    }
                }
            }
        } else if (QualityAnalysisEnum.WEEK_QUALITY.getCode().equals(qualityAnalysisType)) {
            list = IFiveParameterRepository.getFiveParameterExamineData(startDate, endDate, stationCodeList);
            shouldTransmitted = DateUtil.differentDays(startDate, endDate) + 1;
        } else if (QualityAnalysisEnum.MULTIPOINT_LINEARITY.getCode().equals(qualityAnalysisType)) {
            list = IMultipointLinearityRepository.getMultipointLinearityExamineData(startDate, endDate, stationCodeList);
            shouldTransmitted = DateUtil.differentDays(startDate, endDate) + 1;
        } else if (QualityAnalysisEnum.INTEGRATED_INTERVENTION.getCode().equals(qualityAnalysisType)) {
            list = IIntegratedInterventionRepository.getIntegratedInterventionExamineData(startDate, endDate, stationCodeList);
            shouldTransmitted = DateUtil.differentDays(startDate, endDate) + 1;
        } else if (QualityAnalysisEnum.REAL_WATER_SAMPLE_COMPARISON.getCode().equals(qualityAnalysisType)) {
            list = IRealWaterSampleComparisonRepository.getRealWaterSampleComparisonExamineData(startDate, endDate, stationCodeList);
            shouldTransmitted = DateUtil.differentDays(startDate, endDate) + 1;
        } else if (QualityAnalysisEnum.RECOVERY.getCode().equals(qualityAnalysisType)) {
            list = IRecoveryRepository.getRecoveryExamineData(startDate, endDate, stationCodeList);
            shouldTransmitted = DateUtil.differentDays(startDate, endDate) + 1; // 因为查询条件时间包含当天数据,故要加1
        }
        // 常规五参数、多点线性、集成干预、实际水样、加标回收率数据封装
        if (!QualityAnalysisEnum.DAY_QUALITY.getCode().equals(qualityAnalysisType)) {
            for (Map<String, Object> map : list) {
                String areaName = map.get("AREA_NAME").toString();
                String basinName = map.get("BASIN_NAME").toString();
                String operationName = map.get("OPERATION_NAME") == null ? "" : map.get("OPERATION_NAME").toString();
                String stationCode = map.get("STATION_CODE").toString();
                String stationName = map.get("STATION_NAME").toString();
                String indexCode = map.get("INDEX_CODE").toString();
                Double count = Double.valueOf(map.get("COUNT").toString()); // 实传数量
                Double qualified = Double.valueOf(map.get("QUALIFIED").toString()); // 合格数量
                String qualifiedRate = qualified == 0.0 || count == 0.0 ? "0" : ScaleUtil.sciCalSix(qualified * 100 / count, 1); // 计算合格率
                String completionRate = qualified == 0.0 || shouldTransmitted == 0.0 ? "0"
                        : ScaleUtil.sciCalSix(qualified * 100 / shouldTransmitted, 1); // 计算完成率
                if (!valueMap.containsKey(stationCode)) {
                    resultMap = new HashMap<String, Object>();
                    qualifiedRateList = new ArrayList<Double>();
                    completionRateList = new ArrayList<Double>();
                    result.add(resultMap);
                    valueMap.put(stationCode, resultMap);
                    valueMap.put(stationCode + "qualified", qualifiedRateList);
                    valueMap.put(stationCode + "completion", completionRateList);
                } else {
                    resultMap = (Map<String, Object>) valueMap.get(stationCode);
                    qualifiedRateList = (List<Double>) valueMap.get(stationCode + "qualified");
                    completionRateList = (List<Double>) valueMap.get(stationCode + "completion");
                }
                if (QualityAnalysisEnum.WEEK_QUALITY.getCode().equals(qualityAnalysisType)) {
                    // 常规五参数只统计下面四个因子
                    if (WEEK_QUALITY_INDEX.contains(indexCode)) {
                        qualifiedRateList.add(Double.valueOf(qualifiedRate));
                        completionRateList.add(Double.valueOf(completionRate));
                    }
                } else {
                    qualifiedRateList.add(Double.valueOf(qualifiedRate));
                    completionRateList.add(Double.valueOf(completionRate));
                }
                resultMap.put("areaName", areaName);
                resultMap.put("basinName", basinName);
                resultMap.put("operationName", operationName);
                resultMap.put("stationName", stationName);
                resultMap.put(indexCode + "_qualifiedRate", qualifiedRate);
                resultMap.put(indexCode + "_completionRate", completionRate);
                resultMap.put("appraiseQualifiedRate",
                        ScaleUtil.sciCalSix(qualifiedRateList.stream().collect(Collectors.averagingDouble((Double::doubleValue))), 1)); // 评价合格率
                resultMap.put("appraiseCompletionRate",
                        ScaleUtil.sciCalSix(completionRateList.stream().collect(Collectors.averagingDouble((Double::doubleValue))), 1)); // 评价完成率
            }
        }
        boolean pageFlag = pageObject != null && pageObject.getPageNumber() != null && pageObject.getPageSize() != null;
        if (pageFlag) {
            Page<Map<String, Object>> page = PageUtil.inventedPage(result, pageObject);
            return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(result);
    }

}
